<template>
  <div class="father">
    <h3>父组件</h3>
    <h4 v-show="toy">子给的玩具：{{ toy }}</h4>
    <div>
      <button @click="callChildMethod">调用子组件方法</button>
    </div>
    <!-- 给子组件Child绑定事件 -->
    <Child @send-toy="saveToy" ref="childRef" />
  </div>

  <div class="box">
    <button @click="loadComponent">加载异步组件</button>
    <button @click="addOne" class="margL">(shallowRef){{ state.count }}加1</button>
    <button class="margL" @click="add">reactive解构丢失响应式：{{ num }}</button>
    <button class="margL" @click="add3">toRefs解决数据响应式问题:{{ age }}</button>
    <component :is="AsyncComponent" v-if="AsyncComponent"></component>

    <div v-else class="loading">
      <p>加载中...</p>
      <!-- 可以添加加载动画 -->
      <div class="spinner"></div>
    </div>
  </div>
  <div class="box">
    <b>teleport <button @click="show = true">打开模态框</button></b>
    <MyModal :visible="show" @close="show = false"></MyModal>
  </div>
  <div class="box">
    <Suspense>
      <!-- 主要内容（异步组件） -->
      <template #default>
        <UserCard></UserCard>
      </template>
      <!-- 加载状态回退 -->
      <template #fallback>
        <div class="loading">
          <div class="spinner" style="margin-top: 1px">加载中</div>
        </div>
      </template>
    </Suspense>
  </div>

  <div>
    <b>多个元素的模板引用</b>
    <ul>
      <li v-for="(item, index) in list" :key="index" :ref="setRefs">{{ item }}</li>
    </ul>
  </div>
  <div><b>获取全局对象：</b>{{ name }}</div>
  <div>
    <b>获取proxy访问组件实例(this)</b>
  </div>
  <div>
    <b>keep-alive 组件必须设置name,才能被keep-alive正确识别</b>
    <div>
      <button @click="currentKey = 'OneTab'" class="curBox">Tab one</button>
      <button @click="currentKey = 'TwoTab'" class="curBox">Tab two</button>
      <KeepAlive>
        <component :is="current"></component>
      </KeepAlive>
    </div>
  </div>
</template>

<script setup lang="ts" name="Father">
import Child from './Child.vue'
import MyModal from './MyModal.vue'
import UserCard from './UserCard.vue'
import OneTab from './One.vue'
import TwoTab from './Two.vue'

import {
  ref,
  onMounted,
  shallowRef,
  isRef,
  triggerRef,
  customRef,
  defineAsyncComponent,
  getCurrentInstance,
  provide,
  computed,
  reactive,
  toRefs,
  toRef,
  unref,
} from 'vue'
const show = ref(false)
// 数据
let toy = ref('')
console.log('toy', toy)
console.log('isRef(toy)', isRef(toy))

const state = shallowRef({ count: 0 })
const state1 = reactive({ num: 1 })
console.log('state1', state1)
console.log('原始值', unref(state))

let { num } = state1
console.log('num', num)
const person = reactive({ xm: '李明', age: 33 })

// let { xm, age } = toRefs(person)
// console.log('xm', xm)
let { xm } = toRefs(person)
console.log('新xm获取值', xm.value)
// 用于保存传递过来的玩具
function saveToy(value: string) {
  console.log('saveToy', value)
  toy.value = value
}

const childRef = ref(null)
const callChildMethod = () => {
  console.log('1', childRef.value)

  if (childRef.value?.sayHi) {
    childRef.value.sayHi()
  } else {
    console.warn('子组件方法不可用')
  }
}
const AsyncComponent = shallowRef(null)
const loadComponent = () => {
  AsyncComponent.value = defineAsyncComponent({
    //  loader: () => import('./MyAsyncComponent.vue'),
    // 性能优化​​：使用 webpack magic comments 预加载
    loader: () => import(/* webpackPrefetch: true */ './MyAsyncComponent.vue'),
    // loadingComponent: () => import('./LoadingCom.vue'),
    loadingComponent: {
      template: '<div>hh加载中...</div>',
    },
    delay: 200, // 设定延迟
    timeout: 3000, // 设定超时
    suspensible: false, // 禁用 Suspense 包装

    //  errorComponent: () => import('./ErrorComponent.vue'), // 可选错误组件
    // onError: (error, retry, fail) => {
    //   // 错误处理逻辑
    //   console.error('组件加载失败:', error)
    //   retry() // 可以重试
    // }
  })
}
const list = ['vue', 'react', 'angular']
const itemRefs = ref([])

function setRefs(el) {
  if (el) {
    itemRefs.value.push(el)
  }
}
const name = ref(null)
function useGlobalProp() {
  const instance = getCurrentInstance()
  name.value = instance?.appContext.config.globalProperties['name']
}
useGlobalProp()
const instance = getCurrentInstance()
const proxy = instance?.proxy
onMounted(() => {
  console.log('组件代理对象:', proxy)
})
provide('theme', 'dark')
const components = { OneTab, TwoTab }
const currentKey = ref('OneTab')
const current = computed(() => components[currentKey.value])
const arr = reactive([3, 4])
const addOne = () => {
  state.value.count++
  triggerRef(state)
  arr.push(99)
  console.log('state.value.count', state.value.count, arr)
}
const add = () => {
  num++
  console.log('num', num)
}
const add3 = () => {
  age.value++
  xm.value += 'm'
  console.log('xm', xm)
}
</script>

<style scoped>
.curBox {
  cursor: pointer;
}
.box {
  padding: 14px 12px;
}
.father {
  background-color: rgb(165, 164, 164);
  padding: 20px;
  border-radius: 10px;
}
.father button {
  margin-right: 5px;
}
.loading {
  color: #666;
  text-align: center;
  padding: 20px;
}

.spinner {
  border: 4px solid rgba(0, 0, 0, 0.1);
  border-radius: 50%;
  border-top: 4px solid #3498db;
  width: 30px;
  height: 30px;
  animation: spin 1s linear infinite;
  margin: 20px auto;
}

@keyframes spin {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}
.margL {
  margin-left: 10px;
}
</style>
